import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:kq_flutter_core_widget/config/kq_core_global.dart';
import 'package:kq_flutter_tv_widgets/widgets/pullDown/pull_down_menu.dart';
import 'package:kq_flutter_tv_widgets/widgets/pullDown/pull_down_menu_controller.dart';
import '../../resources/kq_theme_colors.dart';
import 'package:kq_flutter_core_widget/utils/ex/kq_ex.dart';
import 'package:kq_flutter_core_widget/utils/str_util.dart';
import 'package:kq_flutter_core_widget/utils/kq_sp_util.dart';
import '../../resources/l10n/kq_intl.dart';

import '../../theme/kq_theme_manager.dart';
import '../button/kq_checked_button.dart';
import '../button/kq_outline_button.dart';
import '../chooseItemView/kq_choose_item_view.dart';
import '../searchBar/kq_search_bar.dart';
import 'entity/drop_down_option.dart';

class PullDownMenuSimple<T extends DropDownOption> extends StatefulWidget {
  final List<List<T>> listData;
  final List<dynamic> chosenData;

  ///选择单选数据时回调
  final Function(T data, int menuIndex)? callBack;

  ///选择单选数据时回调，返回了controller
  final Function(T data, int menuIndex, PullDownMenuController controller)?
      callBackWithController;

  ///选择多选数据时回调
  final Function(List<T> data, int menuIndex)? callBackMulti;

  ///选择多选数据时回调，返回了controller
  final Function(
          List<T> data, int menuIndex, PullDownMenuController controller)?
      callBackMultiWithController;

  /// 当前菜单回调，展开还是收起，当外部自定义菜单收起时可调用menuController.resetPullDownState(),重置pulldown状态
  final Function(int index, bool isShow, PullDownMenuController menuController)?
      getCurrentStatus;

  /// 是否时时搜索，默认是实时搜索
  final bool Function(int menuIndex)? aliveTimeSearch;

  final PullDownMenuController? controller;

  ///是否禁止下拉
  final bool Function(int menuIndex)? disabledRender;

  ///是否是多选，默认单选
  final bool? Function(int menuIndex)? isMultiChoose;

  ///是否需要保存在本地的key
  final String? Function(int menuIndex)? saveKey;

  /// 全选文本
  final String? Function(int menuIndex)? multiChooseText;

  /// 全选后文本
  final String? Function(int menuIndex)? multiChosenText;

  /// 操作按钮文本
  final String? Function(int menuIndex)? multiBottomText;

  /// 选择多少项时限定过滤回调，默认不限定，限定的话，选择不生效，回调不执行，限定返回[true]，不限定返回[false]或则null
  final bool? Function(List<T> data, int menuIndex)? callbackMultiFilter;

  /// 隐藏标题title上显示有 | 后面的内容，true隐藏，false显示，默认为false
  final bool? Function(int menuIndex)? hideEndSuffix;

  ///搜索的内容
  final String? Function(int menuIndex)? searchString;

  ///背景颜色
  final Color bgColor;

  const PullDownMenuSimple({
    super.key,
    required this.listData,
    required this.chosenData,
    this.callBack,
    this.callBackWithController,
    this.getCurrentStatus,
    this.aliveTimeSearch,
    this.controller,
    this.disabledRender,
    this.isMultiChoose,
    this.multiChooseText,
    this.multiChosenText,
    this.multiBottomText,
    this.saveKey,
    this.callBackMulti,
    this.callBackMultiWithController,
    this.callbackMultiFilter,
    this.hideEndSuffix,
    this.searchString,
    this.bgColor = Colors.white,
  });

  @override
  State<StatefulWidget> createState() => PullDownMenuSimpleState<T>();

  ///获取保存的筛选ids，默认用","分割，可以自定义分割符
  static String? getSavedIds(String saveKey, {String split = ","}) {
    if (saveKey.isNotNullOrEmpty) {
      List<String>? chosenDataIds = KqCoreGlobal.prefs
          ?.getStringList("$saveKey${PullDownMenuSimpleState.suffixIds}");
      return StrUtil.concatDynamic(chosenDataIds, (t) => t, split: split);
    }
    return null;
  }

  ///获取保存的筛选names，默认用","分割，可以自定义分割符
  static String? getSavedNames(String saveKey, {String split = ","}) {
    if (saveKey.isNotNullOrEmpty) {
      List<String>? chosenDataNames = KqCoreGlobal.prefs
          ?.getStringList("$saveKey${PullDownMenuSimpleState.suffixNames}");
      return StrUtil.concatDynamic(chosenDataNames, (t) => t, split: split);
    }
    return null;
  }

  ///清除保存的多选数据
  static Future clearSaved(String saveKey) async {
    if (saveKey.isNotNullOrEmpty) {
      await KqSpUtil.setStringList(
          "$saveKey${PullDownMenuSimpleState.suffixNames}", null);
      await KqSpUtil.setStringList(
          "$saveKey${PullDownMenuSimpleState.suffixIds}", null);
    }
  }

  ///是否选择了全部分类
  static bool getIsChosenAll(String saveKey) {
    if (saveKey.isNotNullOrEmpty) {
      return KqSpUtil.getBool(
              "$saveKey${PullDownMenuSimpleState.suffixChosenAll}") ??
          false;
    }
    return false;
  }
}

class PullDownMenuSimpleState<T extends DropDownOption>
    extends State<PullDownMenuSimple<T>> {
  static String suffixIds = "ids";
  static String suffixNames = "names";
  static String suffixChosenAll = "chosenAll";
  List<dynamic> _chosenData = [];

  @override
  void initState() {
    _chosenData = widget.chosenData;
    for (int i = 0; i < widget.chosenData.length; i++) {
      String? saveKey = widget.saveKey?.call(i);
      if (saveKey.isNotNullOrEmpty) {
        bool isAllChoose = PullDownMenuSimple.getIsChosenAll(saveKey!);
        if (isAllChoose) {
          String allChoose = (widget.multiChooseText?.call(i)) ??
              (widget.multiChosenText?.call(i)) ??
              KqIntl.currentResource.selectAll;
          _chosenData[i] = allChoose;
        } else {
          String? names = PullDownMenuSimple.getSavedNames(saveKey);
          if (names.isNotNullOrEmpty) {
            _chosenData[i] = names;
          }
        }
      }
    }
    super.initState();
  }

  @override
  void didUpdateWidget(covariant PullDownMenuSimple<T> oldWidget) {
    if (widget.listData.isNotNullOrEmpty) {
      for (int i = 0; i < widget.chosenData.length; i++) {
        String? saveKey = widget.saveKey?.call(i);
        if (saveKey.isNotNullOrEmpty) {
          List<String>? chosenDataIds =
              KqCoreGlobal.prefs?.getStringList("${saveKey!}$suffixIds");
          if (chosenDataIds.isNotNullOrEmpty) {
            for (T item in widget.listData[i]) {
              for (String id in chosenDataIds!) {
                if (item.titleId == id) {
                  item.chosen = true;
                }
              }
            }
          }
        }
      }
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return PullDownMenu(
      bgColor: widget.bgColor,
      menuWidgetHeight: (menuIndex) {
        if (widget.isMultiChoose?.call(menuIndex) ?? false) {
          return widget.listData[menuIndex].length >= 8
              ? 584.r
              : 64.r +
                  widget.listData[menuIndex].length * 1.r +
                  widget.listData[menuIndex].length * 64.r;
        } else {
          return widget.listData[menuIndex].length >= 8
              ? 584.r
              : widget.listData[menuIndex].length * 1.r +
                  widget.listData[menuIndex].length * 64.r;
        }
      },
      isShowCustomWidget: (menuIndex) =>
          (widget.isMultiChoose?.call(menuIndex)) ?? false,
      initChosenData: _chosenData,
      pullDownController: widget.controller,
      disabledRender: widget.disabledRender,
      titleRender: (titleData, menuIndex) {
        if (titleData is List<T>) {
          String? s = '';
          if (titleData.length == widget.listData[menuIndex].length ||
              titleData.isEmpty) {
            s = widget.multiChooseText?.call(menuIndex) ??
                KqIntl.currentResource.selectAll;
          } else {
            for (int i = 0; i < titleData.length; i++) {
              if (i == 0) {
                if (!(widget.hideEndSuffix?.call(menuIndex) ?? false)) {
                  s = '${titleData[0].title}';
                } else {
                  s = '${titleData[0].title?.split(" | ")[0]}';
                }
              } else {
                if (!(widget.hideEndSuffix?.call(menuIndex) ?? false)) {
                  s = '$s,${titleData[i].title}';
                } else {
                  s = '$s,${titleData[i].title?.split(" | ")[0]}';
                }
              }
            }
          }
          return s!;
        } else if (titleData is T) {
          if (!(widget.hideEndSuffix?.call(menuIndex) ?? false)) {
            return titleData.title ?? "";
          } else {
            return titleData.title?.split(" | ")[0] ?? "";
          }
        } else {
          return titleData;
        }
      },
      menuDataRender: (menuIndex) =>
          (widget.isMultiChoose?.call(menuIndex) ?? false)
              ? null
              : widget.listData[menuIndex],
      menuItemRender: (menuIndex, p0) {
        return p0.title;
      },
      isDataSame: (p0, p1) {
        if (p0 is T && p1 is T) {
          if (p0.titleId == p1.titleId) {
            return true;
          } else {
            return false;
          }
        } else {
          return false;
        }
      },
      isSelfControlHeaderData: (index) => false,
      pullDownCallback: (item, menuIndex, menuController) {
        widget.callBack?.call(item, menuIndex);
        widget.callBackWithController?.call(item, menuIndex, menuController);
      },
      searchResultCallback: (menuIndex, searchContent) {
        return _searchData(menuIndex, searchContent);
      },
      getCurrentStatus: (index, isShow, menuController) {
        widget.getCurrentStatus?.call(index, isShow, menuController);
      },
      aliveTimeSearch: widget.aliveTimeSearch ?? (menuIndex) => true,
      menuCustomWidgetRender: (menuIndex, listState) {
        if (widget.isMultiChoose?.call(menuIndex) ?? false) {
          return _MultiChooseWidget(
            data: widget.listData[menuIndex],
            multiChooseText: widget.multiChooseText?.call(menuIndex),
            multiChosenText: widget.multiChosenText?.call(menuIndex),
            multiBottomText: widget.multiBottomText?.call(menuIndex),
            aliveTimeSearch: widget.aliveTimeSearch?.call(menuIndex),
            onChosen: (chosenData) {
              if (!((widget.callbackMultiFilter?.call(chosenData, menuIndex)) ??
                  false)) {
                listState.setChooseItemData(chosenData, changeIndex: menuIndex);

                ///保存选择的数据
                String? saveKey = widget.saveKey?.call(menuIndex);
                if (saveKey.isNotNullOrEmpty) {
                  KqCoreGlobal.prefs?.setStringList(
                      "${saveKey!}$suffixIds",
                      StrUtil.concatValueToList<String, T>(
                          chosenData, (t) => t.titleId ?? ""));

                  if (chosenData.isEmpty ||
                      chosenData.length == widget.listData[menuIndex].length) {
                    String allChoose =
                        (widget.multiChooseText?.call(menuIndex)) ??
                            (widget.multiChosenText?.call(menuIndex)) ??
                            KqIntl.currentResource.selectAll;
                    KqCoreGlobal.prefs
                        ?.setStringList("${saveKey!}$suffixNames", [allChoose]);
                    KqCoreGlobal.prefs
                        ?.setBool("$saveKey$suffixChosenAll", true);
                  } else {
                    KqCoreGlobal.prefs?.setStringList(
                        "${saveKey!}$suffixNames",
                        StrUtil.concatValueToList<String, T>(
                            chosenData,
                            (t) => !(widget.hideEndSuffix?.call(menuIndex) ??
                                    false)
                                ? t.title ?? ""
                                : t.title?.split(" | ")[0] ?? ""));
                    KqCoreGlobal.prefs
                        ?.setBool("$saveKey$suffixChosenAll", false);
                  }
                }

                widget.callBackMulti?.call(chosenData, menuIndex);
                widget.callBackMultiWithController
                    ?.call(chosenData, menuIndex, listState);
              }
            },
            searchString: widget.searchString?.call(menuIndex),
          );
        }
        return null;
      },
    );
  }

  _searchData(int index, String content) {
    List<T> data = widget.listData[index];
    if (content.isEmpty) {
      return data;
    }
    List<dynamic> list = [];
    for (T t in data) {
      if (t.title != null &&
          t.title!.isNotEmpty &&
          t.title!.toUpperCase().contains(content.toUpperCase())) {
        list.add(t);
      }
    }
    return list;
  }
}

class _MultiChooseWidget<T extends DropDownOption> extends StatefulWidget {
  /// 全选文本
  final String? multiChooseText;

  /// 全选后文本
  final String? multiChosenText;

  /// 操作按钮文本
  final String? multiBottomText;

  ///数据
  final List<T> data;

  ///选择回调
  final Function(List<T> chosenData)? onChosen;

  /// 是否时时搜索，默认是实时搜索
  final bool? aliveTimeSearch;

  ///搜索的内容
  final String? searchString;

  const _MultiChooseWidget({
    required this.data,
    this.multiChosenText,
    this.multiBottomText,
    this.multiChooseText,
    this.onChosen,
    this.aliveTimeSearch,
    this.searchString,
  });

  @override
  State<StatefulWidget> createState() => _MultiChooseWidgetState<T>();
}

class _MultiChooseWidgetState<T extends DropDownOption>
    extends State<_MultiChooseWidget<T>> {
  bool isAllChoose = false;
  List<T> searchData = [];
  TextEditingController controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    _flashAllChoose();
    searchData = widget.data;
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Visibility(
          visible: widget.data.length > 8,
          child: KqSearchBar(
            editController: controller,
            onSubmit: (value, state) {
              if (!(widget.aliveTimeSearch ?? true)) {
                if (value.isNullOrEmpty) {
                  _multiCancelSearch();
                } else {
                  _multiStartSearch(value);
                }
              }
            },
            onCancel: () {
              _multiCancelSearch();
            },
            onChanged: (value) {
              if (widget.aliveTimeSearch ?? true) {
                if (value.isNullOrEmpty) {
                  _multiCancelSearch();
                } else {
                  _multiStartSearch(value);
                }
              }
            },
          ),
        ),
        Container(
          width: double.infinity,
          height: 1.r,
          color: KqThemeColors.lineColor,
        ),
        Expanded(
          child: MediaQuery.removePadding(
              context: context,
              removeTop: true, // flutter真的坑，listview自带顶部padding
              removeBottom: true,
              child: searchData.isNullOrEmpty
                  ? Container(
                      color: Colors.white,
                      width: double.infinity,
                      padding: EdgeInsets.fromLTRB(12.r, 10.r, 0, 0),
                      height: 64.r,
                      child: Text(
                        KqIntl.currentResource.noDataTip,
                        textAlign: TextAlign.start,
                        style: TextStyle(
                            fontSize: KqThemeManager.getPullDownMenuConfig()
                                .headFontSize,
                            color: KqThemeColors.text59),
                      ),
                    )
                  : ListView.builder(
                      itemCount: searchData.length,
                      itemBuilder: (BuildContext context, int index) {
                        T entity = searchData[index];
                        return KqChooseItemView(
                          isChecked: entity.chosen,
                          title: entity.title,
                          updateCheckedWhenBuild: true,
                          fontSize: KqThemeManager.getPullDownMenuConfig()
                              .menuFontSize,
                          onItemTap: (check) {
                            entity.chosen = check;
                            if (!check) {
                              isAllChoose = false;
                            } else {
                              _flashAllChoose();
                            }
                            setState(() {});
                          },
                        );
                      })),
        ),
        Container(
          width: double.infinity,
          height: 1.r,
          color: KqThemeColors.lineColor,
        ),
        Container(
          height: 64.r,
          width: double.infinity,
          padding: EdgeInsets.only(left: 15.r - 8.r, right: 15.r),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              KqCheckedButton(
                isChecked: isAllChoose,
                horizontalPadding: 8.r,
                verticalPadding: 8.r,
                checkedString: widget.multiChooseText ??
                    widget.multiChosenText ??
                    KqIntl.currentResource.selectAll,
                unCheckedString: widget.multiChosenText ??
                    widget.multiChooseText ??
                    KqIntl.currentResource.selectAll,
                updateCheckedWhenBuild: true,
                onCheckedChanged: (checked) {
                  if (widget.data.isNotNullOrEmpty) {
                    for (T item in widget.data) {
                      item.chosen = checked;
                    }
                  }
                  isAllChoose = checked;
                  setState(() {});
                },
              ),
              const Spacer(),
              Container(
                margin: EdgeInsets.symmetric(vertical: 6.r),
                child: KqOutlineButton(
                  title: widget.multiBottomText ?? KqIntl.currentResource.ok,
                  borderColor: KqThemeColors.textBlue,
                  bgColor: KqThemeColors.textBlue,
                  textColor: KqThemeColors.bgWhite,
                  verticalPadding: 0,
                  onTap: (d) {
                    List<T> chosenData = [];
                    if (searchData.isNotNullOrEmpty) {
                      for (T item in searchData) {
                        if (item.chosen) {
                          chosenData.add(item);
                        }
                      }
                    }
                    widget.onChosen?.call(chosenData);
                  },
                ),
              ),
            ],
          ),
        )
      ],
    );
  }

  _flashAllChoose() {
    bool flag = true;
    for (T item in widget.data) {
      if (!item.chosen) {
        isAllChoose = false;
        flag = false;
        break;
      }
    }
    if (flag) {
      isAllChoose = true;
    }
  }

  _multiCancelSearch() {
    searchData = widget.data;
    setState(() {});
  }

  _multiStartSearch(String content) {
    searchData = _searchData(content);
    setState(() {});
  }

  _searchData(String content) {
    List<T> data = widget.data;
    if (content.isEmpty) {
      return data;
    }
    List<T> list = [];
    for (T t in data) {
      if (widget.searchString.isNotNullOrEmpty) {
        if (widget.searchString!
            .toUpperCase()
            .contains(content.toUpperCase())) {
          list.add(t);
        }
      } else {
        if (t.title != null &&
            t.title!.isNotEmpty &&
            t.title!.toUpperCase().contains(content.toUpperCase())) {
          list.add(t);
        }
      }
    }
    return list;
  }
}
